# -*- coding: utf-8 -*-

import asyncio
import json
import os
import threading
import time

from requests import Response
import utils
import wqb

class Simulator:
    def __init__(self,  wqbs: wqb.WQBSession, concurrency: int = 8):
        """
        Args:
            wqbs: wqb.WQBSession
            concurrency: 并发数
        """
        self.wqbs = wqbs
        self.concurrency = concurrency
        self.batch_size = self.concurrency * 10
        self.last_login_time = 0
    
    async def simulate(self, alphas:list):
        """回测"""

        # Step 6: Run simulations
        print("\n" + "="*60)
        print("运行回测")
        print("="*60)
        print("开始多重回测(multi-simulatioin)并发回测...")
        
        try:
            resps = await self.wqbs.concurrent_simulate(
                alphas, 
                self.concurrency, 
                log_gap=10
            )
            
            # Print results
            print("\n" + "="*60)
            print("回测结果")
            print("="*60)
            
            print(f"成功完成 {len(resps)} 个多重回测(multi-simulatioin)槽的回测")
            
            print("\nAlpha IDs:")
            for i, resp in enumerate(resps):
                try:
                    alpha_id = resp.json()['alpha']
                    print(f"  {i+1:4d}. {alpha_id}")
                except Exception as e:
                    print(f"  {i+1:4d}. 错误: {e}")
                    
        except KeyboardInterrupt:
            print("\n\n⚠️  回测被用户中断")
        except Exception as e:
            print(f"\n❌ 回测错误: {e}")
        
        print("\n✅ 处理完成!")
        

    def deal_resp(self, resp:Response, alpha:dict) -> str:
        """处理回测结果"""
        try:
            if resp.status_code // 100 != 2:
                print(f'回测 {alpha['regular']} 失败: {resp.status_code}')
                return None
            data = json.loads(resp.text)
            if data['status'] != 'COMPLETE':
                print(f'回测 {alpha["regular"]} 失败: {data["status"]}')
                return None
            else:
                print(f'回测 {alpha["regular"]} 成功')
            return 1
        except Exception as e:
            print(f'回测 {alpha['regular']} 失败: {resp.text}')
            return None
    def simulate_for_robust(self, alpha_list: list):
        """回测 Alpha 列表中的所有 Alpha"""
        # 检查是否有已处理的 Alpha ID 文件
        processed_alpha_ids = set()
        simulated_alphas_file = './results/simulated_alphas.csv'
        if os.path.exists(simulated_alphas_file):
            with open(simulated_alphas_file, 'r') as f:
                processed_alpha_ids = set(line.strip() for line in f)

        print(f"已处理的 Alpha 表达式数量：{len(processed_alpha_ids)}")
        print(f"开始和已处理的 Alpha 表达式进行比对...")
        # 过滤掉已处理的 Alpha
        alpha_list = [alpha for alpha in alpha_list if utils.hash(alpha) not in processed_alpha_ids]
        # 根据 hash 值过滤掉重复的 Alpha 
        alpha_list = list({utils.hash(alpha): alpha for alpha in alpha_list}.values())

        alpha_ids =[]
        # 如果没有需要处理的 Alpha，直接退出
        if not alpha_list:
            print("所有 Alpha 都已处理完毕，无需继续运行。")
            return alpha_ids

        print(f"共有 {len(alpha_list)} 个未处理的 Alpha 表达式需要回测。")
        print("开始回测...")
        lines = []
        for alpha in alpha_list:
            resp =resp = asyncio.run( self.wqbs.simulate(
                alpha
                , on_nolocation=lambda vars: print(vars['target'], vars['resp'], sep='\n')
                , on_start=self.on_start
                , on_finish=lambda vars: print(vars['resp'])
                , log=f'{self.__class__}#simulate_for_robust'
            ))
            print(resp)
            
            lines.append(f'{utils.hash(alpha)}\n')
            alpha_ids.append(resp.json()['alpha'])
            
        # 将已处理的 Alpha ID 写入文件中
        utils.save_lines_to_file(simulated_alphas_file, lines)
        return alpha_ids

    def on_start(self, vars: dict[str, object]) -> None:
        """在回测开始时调用"""
        # 定时刷新 session（4小时）
        current_time = time.time()
        if current_time - self.last_login_time >4*3600:
            try:
                self.wqbs.delete_authentication()
                self.wqbs.post_authentication()
                self.wqbs.logger.info("定时刷新 session 成功")
                self.last_login_time = current_time # 更新登录时间
            except Exception as e:
                self.wqbs.logger.error(f"定时刷新 session 失败: {e}")

        print(vars['url'])
            
           